<?php
namespace core\models;
/**
 * Html处理
 * @package core\models
 * @author  ZhouHaoHua <53027327@qq.com>
 * @package
 */
class Html {
    /**
     * 重定向到$url(如果url中有\n或者\r,重定向到首页)
     * @param string $url         跳转到的目标
     * @param int    $status_code 状态码，如：301, 302等
     */
    public static function redirect($url, $status_code = 0) {
        if ($status_code) {
            switch ($status_code) {
                case 301:
                    header("HTTP/1.1 301 Moved Permanently");
                    break;
                case 302:
                    header("HTTP/1.1 302 Move temporarily");
                    break;
                /*case 404:
                    header("HTTP/1.1 404 Not Found");
                    header("Status: 404 Not Found");
                    break;*/
            }
        }
        header('Location: ' . $url);
        exit;
    }

    /**
     * 判断url地址是否有效
     * @param string $url 要检查的url
     * @return bool 若有效并且可访问则返回true
     */
    public static function isUrl($url) {
        $headers = @get_headers($url);
        if ($headers) {
            $head = explode(' ', $headers[0]);
            if (!empty($head[1]) && intval($head[1]) == 200) {
                return true;
            }
        }
        return false;
    }

    /**
     * 生成一个符合本系统的超级链接地址
     * @param string $page       控制器的文件名(如index.php,product.php)，若此值是一个完整url地址将不做任何处理直接原样返回！
     * @param string $parameters 参数(如cPath=1_4&products_id=1)
     * @param string $connection 连接方式(SSL or NONSSL)
     * @param bool   $add_session_id
     * @param bool   $search_engine_safe
     * @param bool   $for_seo    是否启用seo模式默认启用，如果不启用seo模式时直接调用href_link_noseo
     * @return string
     */
    public static function href_link($page = '', $parameters = '', $connection = 'NONSSL', $add_session_id = false, $search_engine_safe = false, $for_seo = true) {
        $link = null;
        if (preg_match('@^http[s]?://@', $page)) {
            return $page;
        }
        if ($page == 'index.php') {
            $link = '/';
        }
        //由于此系统的目录下面的文件基本都被移到controller文件夹，所以这里要处理一下$page
        //IS_BACKSTAGE !==true &&
        if ($page && strpos($page, '/') === false && in_array(
                $page, array(
                    'index.php', 'ajax.php',
                    '404.php', '403.php'
                )
            ) === false
        ) {
            $parameters = 'mod=' . substr($page, 0, -4) . ($parameters ? '&' . $parameters : '');
            $page       = 'index.php';
        }

        if ($link == '/') { //省略index.php
            $page = '';
        }
        $link = '/' . $page . ($parameters ? '?' . $parameters : '');

        return $link;
    }

    /**
     * 非seo方式的超级链接
     * tep_href_link_noseo 链接的包装函数(用于非SEO的情况，如ajax提交数据的url地址要用此函数)
     * @param string $page       控制器的文件名(如index.php,product.php)
     * @param string $parameters 参数(如cPath=1_4&products_id=1)
     * @param string $connection 连接方式(SSL or NONSSL)
     * @param bool   $add_session_id
     * @param bool   $search_engine_safe
     * @return string
     */
    public static function href_link_noseo($page = '', $parameters = '', $connection = 'NONSSL', $add_session_id = false, $search_engine_safe = false) {
        if (preg_match('@^http[s]?://@', $page)) {
            return $page;
        }
        if ($page == 'index.php') {
            $link = '/';
        }
        //由于此系统的目录下面的文件基本都被移到controller文件夹，所以这里要处理一下$page
        //IS_BACKSTAGE !==true &&
        if ($page && strpos($page, '/') === false && in_array(
                $page, array(
                    'index.php', 'ajax.php',
                    '404.php', '403.php'
                )
            ) === false
        ) {
            $parameters = 'mod=' . substr($page, 0, -4) . ($parameters ? '&' . $parameters : '');
            $page       = 'index.php';
        }

        if ($link == '/') { //省略index.php
            $page = '';
        }
        $link = '//' . Z_TOP_WWW . '/' . $page . ($parameters ? '?' . $parameters : '');

        return $link;
    }
    ////
    // Output a form input field
    /**
     * 输出表单input栏位 , POST > GET > $
     * @param string $name           名称
     * @param string $value          input中的值
     * @param string $parameters     其他参数
     * @param string $type           input的类型
     * @param bool   $reinsert_value 是否自动获取同名全局变量的值
     * @param bool   $enterkey       是否在敲回车键时转换简繁体 （已经没用了啦）
     * @return string
     */
    public static function input_field($name, $value = '', $parameters = '', $type = 'text', $reinsert_value = true, $enterkey = false) {
        $nameStr = $name == '' ? '' : ' name="' . Strings::SafeOut($name) . '"'; //vincent add
        $field   = '<input type="' . Strings::SafeOut($type) . '"' . $nameStr;
        if ($value || $value == '0') {
            $field .= ' value="' . Strings::SafeOut((string)$value) . '"';
        } elseif ($reinsert_value == true) {
            if ((isset($_POST[$name]))) {
                $field .= ' value="' . Strings::SafeOut(stripslashes($_POST[$name])) . '"'; //转编码
            } elseif ((isset($_GET[$name]))) {
                $field .= ' value="' . Strings::SafeOut(stripslashes($_GET[$name])) . '"'; //转编码
            } elseif ((isset($_COOKIE[$name]))) {
                $field .= ' value="' . Strings::SafeOut(stripslashes($_COOKIE[$name])) . '"'; //转编码
            }
        }
        if ($parameters)
            $field .= ' ' . $parameters;

        $field .= ' />';

        return $field;
    }

    /**
     * 生成只读输入框
     * @param        $name       名称
     * @param string $value      值
     * @param string $parameters 除了readonly属性之外的其他属性字符串
     * @return string 返回只读输入框的html代码
     */
    public static function inputReadonlyField($name, $value = '', $parameters = '') {
        $parameters .= ' readonly="readonly" ';
        return self::input_field($name, $value, $parameters);
    }

    /**
     * 生成一个日期选择框
     * @param        $name       名称
     * @param string $value      默认值
     * @param string $parameters 其它参数
     * @return string
     */
    public static function inputDate($name, $value = '', $parameters = '') {
        if (!stripos($parameters, 'class')) {
            $parameters .= 'class="textTime" ';
        }
        $parameters .= ' onclick="GeCalendar.SetUnlimited(1); GeCalendar.SetDate(this);" autocomplete="Off" ';
        return self::input_num_en_field($name, $value, $parameters);
    }

    /**
     * 输出表单input栏位,该栏位只允许输入英文和数字
     * @param string $name
     * @param string $value
     * @param string $parameters
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     */
    public static function input_num_en_field($name, $value = '', $parameters = '') {
        if (preg_match('/style="([^"]+)"/', $parameters, $m)) {
            $parameters = preg_replace('/style="([^"]+)"/', '', $parameters);
        }
        //ime-mode,设置或检索是否允许用户激活输入中文，韩文，日文等的输入法(ime)状态;
        //auto : 默认值。不影响ime的状态。与不指定 ime-mode 属性时相同
        //active : 指定所有使用ime输入的字符。即激活本地语言输入法。用户仍可以撤销激活ime
        //inactive : 指定所有不使用ime输入的字符。即激活非本地语言。用户仍可以撤销激活ime
        //disabled : 完全禁用ime。对于有焦点的控件(如输入框)，用户不可以激活ime
        $parameters .= ' style="ime-mode: disabled; ' . $m[1] . '" ';
        return html::input_field($name, $value, $parameters, 'text', true);
    }

    ////
    // Output a form password field
    /**
     * 输出表单input 密码栏位
     */
    public static function input_password_field($name, $value = '', $parameters = 'maxlength="40"') {
        return html::input_field($name, $value, $parameters, 'password', false);
    }

    ////
    // Output a selection field - alias public static function for html::input_checkbox_field() and html::input_radio_field()
    /**
     * 输出一个单选框或者复选框 栏位 - tep_draw_checkbox_field（）和tep_draw_radio_field（）
     */
    public static function selection_field($name, $type, $value = '', $checked = false, $parameters = '') {
        global $_GET, $_POST;

        $selection = '<input type="' . Strings::SafeOut($type) . '" name="' . Strings::SafeOut($name) . '"';

        if (Strings::notNull($value))
            $selection .= ' value="' . Strings::SafeOut($value) . '"';

        if (($checked == true) || (isset($_GET[$name]) && is_string($_GET[$name]) && (($_GET[$name] == 'on') || (stripslashes($_GET[$name]) == $value))) || (isset($_POST[$name]) && is_string($_POST[$name]) && (($_POST[$name] == 'on') || (stripslashes($_POST[$name]) == $value)))) {
            $selection .= ' checked="checked"';
        }

        if (Strings::notNull($parameters))
            $selection .= ' ' . $parameters;

        $selection .= ' />';

        return $selection;
    }

    ////
    // Output a form checkbox field
    /**
     * 输出复选框
     */
    public static function input_checkbox_field($name, $value = '', $checked = false, $parameters = '') {
        return html::selection_field($name, 'checkbox', $value, $checked, $parameters);
    }

    ////
    // Output a form radio field
    /**
     * 输出单选框
     */
    public static function input_radio_field($name, $value = '', $checked = false, $parameters = '') {
        return html::selection_field($name, 'radio', $value, $checked, $parameters);
    }

    ////
    // Output a form textarea field
    // The $wrap parameter is no longer used in the core xhtml template
    /**
     * 输出textarea   $ Wrap参数不再使用核心XHTML模板

     */
    public static function textarea_field($name, $wrap, $width, $height, $text = '', $parameters = '', $reinsert_value = true, $enterkey = true) {

        $field = '<textarea name="' . Strings::SafeOut($name) . '"  cols="' . Strings::SafeOut($width) . '" rows="' . Strings::SafeOut($height) . '"';
        if (Strings::notNull($wrap)) {
            $field .= ' wrap="' . Strings::SafeOut($wrap) . '" ';
        }

        if (Strings::notNull($parameters))
            $field .= ' ' . $parameters;
        $field .= '>';

        if ((isset($_POST[$name])) && ($reinsert_value == true)) {
            $field .= Others::html_to_db(stripslashes($_POST[$name])); //转编码
        } elseif ((isset($_GET[$name])) && ($reinsert_value == true)) {
            $field .= Others::html_to_db(stripslashes($_GET[$name])); //转编码
        } elseif (Strings::notNull($text)) {
            $field .= $text;
        }

        $field .= '</textarea>';

        return $field;
    }
    ////
    // Output a form hidden field
    /**
     * 输出表单隐藏字段
     */
    public static function input_hidden_field($name, $value = '', $parameters = '') {

        $field = '<input type="hidden" name="' . Strings::SafeOut($name) . '"';

        if (Strings::notNull($value)) {
            $field .= ' value="' . Strings::SafeOut($value) . '"';
        } elseif ((isset($_GET[$name]) && is_string($_GET[$name])) || (isset($_POST[$name]) && is_string($_POST[$name]))) {
            if ((isset($_GET[$name]) && is_string($_GET[$name]))) {
                $field .= ' value="' . Strings::SafeOut(stripslashes($_GET[$name])) . '"';
            } elseif ((isset($_POST[$name]) && is_string($_POST[$name]))) {
                $field .= ' value="' . Strings::SafeOut(stripslashes($_POST[$name])) . '"';
            }
        }

        if ($parameters)
            $field .= ' ' . $parameters;

        $field .= ' />';

        return $field;
    }

    ////
    // Hide form elements
    /**
     * 将session_name, session id作为隐藏元素输出,用于参数传递
     */
    public static function input_hidden_session_id() {
        global $session_started, $SID;

        if (($session_started == true) && Strings::notNull($SID)) {
            return html::input_hidden_field(session_name(), session_id());
        }
    }
    /**
     * 生成可多选的下拉Select菜单
     * @param string     $name 下拉框名称
     * @param array      $values 下拉数据array(array('id'=>'ID','text'=>'名称')[,array('id'=>'ID','text'=>'名称')[,...]])
     * @param array      $default 默认选中的值（一维数组）
     * @param string     $parameters 其他下拉框的属性
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     * @date   2017-03-08
     */
    public static function select_field_multiple($name, array $values, $default = array(), $parameters = '') {
        $field = '<select multiple name="' . Strings::SafeOut($name) . '"';

        if (($parameters))
            $field .= ' ' . $parameters;

        $field .= '>';

        for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
            if ($values[$i]['optgroup'] != true || in_array($values[$i]['id'], $default)) {
                $field .= '<option value="' . Strings::SafeOut($values[$i]['id']) . '"';
                if (in_array($values[$i]['id'], $default)) {
                    $field .= ' SELECTED';
                }
                if (($values[$i]['class'])) {
                    $field .= ' class="' . $values[$i]['class'] . '"';
                }
                $field .= '>' . Strings::SafeOut(
                        $values[$i]['text']/*, array(
                            '"' => '&quot;', '\'' => '&#039;',
                            '<' => '&lt;', '>' => '&gt;'
                        )*/
                    ) . '</option>';
            } else {
                $field .= '<optgroup label="' . Strings::SafeOut(
                        $values[$i]['text']/*, array(
                            '"'  => '&quot;',
                            '\'' => '&#039;',
                            '<'  => '&lt;',
                            '>'  => '&gt;'
                        )*/
                    ) . '"';
                if (Strings::SafeOut($values[$i]['class'])) {
                    $field .= ' class="' . $values[$i]['class'] . '"';
                }
                $field .= '></optgroup>';
            }
        }
        $field .= '</select>';

        return $field;
    }


    /**
     * 输出下拉式菜单
     * @param string $name       名称
     * @param array  $values     所有值,数组形式,array('id' => 'id', 'text' => 'text' , 'optgroup'=> false, 'class'=>'class_name');
     * @param string $default    默认值
     * @param string $parameters 附加参数
     * @param bool   $required   是否需要添加必填项标志
     * @return string
     */
    public static function select_field($name, $values, $default = '', $parameters = '', $required = false) {
        $field = '<select name="' . Strings::SafeOut($name) . '"';

        if (($parameters))
            $field .= ' ' . $parameters;

        $field .= '>';

        if (empty($default) && ((isset($_GET[$name]) && is_string($_GET[$name])) || (isset($_POST[$name]) && is_string($_POST[$name])))) {
            if (isset($_GET[$name]) && is_string($_GET[$name])) {
                $default = stripslashes($_GET[$name]);
            } elseif (isset($_POST[$name]) && is_string($_POST[$name])) {
                $default = stripslashes($_POST[$name]);
            }
        }
        for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
            if ($values[$i]['optgroup'] != true || $default == $values[$i]['id']) {
                $field .= '<option value="' . Strings::SafeOut($values[$i]['id']) . '"';
                if ($default == $values[$i]['id']) {

                    $field .= ' SELECTED';
                }
                if (($values[$i]['class'])) {
                    $field .= ' class="' . $values[$i]['class'] . '"';
                }
                $field .= '>' . Strings::SafeOut(
                        $values[$i]['text']/*, array(
                            '"' => '&quot;', '\'' => '&#039;',
                            '<' => '&lt;', '>' => '&gt;'
                        )*/
                    ) . '</option>';
            } else {
                $field .= '<optgroup label="' . Strings::SafeOut(
                        $values[$i]['text']/*, array(
                            '"'  => '&quot;',
                            '\'' => '&#039;',
                            '<'  => '&lt;',
                            '>'  => '&gt;'
                        )*/
                    ) . '"';
                if (Strings::SafeOut($values[$i]['class'])) {
                    $field .= ' class="' . $values[$i]['class'] . '"';
                }
                $field .= '></optgroup>';
            }
        }
        $field .= '</select>';


        if ($required == true)
            $field .= TEXT_FIELD_REQUIRED;

        return $field;
    }

    /**
     * 取得当前页面url的所有get参数
     * @param array $exclude_array 要排除的参数,必须是一维数组
     * @param array $get           数据源，不传就自动取$_GET
     * @return string 返回get参数字符串
     */
    public static function get_url_params($exclude_array = array(), $get = array()) {
        //一定要排除来源的GET参数
        $exclude_array[] = 'utm_source';
        $exclude_array[] = 'utm_medium';
        $exclude_array[] = 'utm_term';
        $exclude_array[] = 'utm_content';
        $exclude_array[] = 'utm_campaign';

        if (!$get) {
            $get = $_GET;
        }
        unset($get['x'], $get['y'], $get[session_name()], $get['error']); /*$get['action'], $get['mod']*/
        foreach ((array)$exclude_array as $gKey) {
            unset($get[$gKey]);
        }
        return http_build_query($get);
        //return tep_get_all_get_params($exclude_array, $get);
    }


    /**
     * 生成一个单行文本框
     * @param string  $name   名称
     * @param string  $value  值
     * @param string  $params 其他属性
     * @param boolean $noIME  是否禁用输入法[默认启用,true则禁用]
     * @author lwkai 14-2-25 ZhouHaoHua <53027327@qq.com> fixed by 14-06-06
     * @return string
     */
    public static function input($name, $value = '', $params = '', $noIME = false) {
        if (!$noIME) {
            return html::input_field($name, $value, $params, 'text', false, false);
        } else {
            return html::input_num_en_field($name, $value, $params);
        }
    }

    /**
     * 生成一个隐藏的文本域
     * @param string $name       文本域的NAME名称
     * @param string $value      值，如果不传，则会从GET中或者POST中找对应名称的值设置。需注意！
     * @param string $parameters 其他隐藏域的HTML属性
     * @author lwkai 14-2-25
     * @return string
     */
    public static function inputHidden($name, $value = '', $parameters = '') {
        return html::input_hidden_field($name, $value, $parameters);
    }

    /**
     * 生成多行文本框
     * @param string $name           文本框名称
     * @param string $text           文本框内容
     * @param string $parameters     文本框其他属性
     * @param string $cols           文本框默认可见宽度[默认50]
     * @param string $rows           文本框默认显示行数[默认5]
     * @param bool   $reinsert_value 是否接收$GLOBALS[$name]做为其值
     * @author lwkai 14-2-25
     * @return string
     */
    public static function inputTextarea($name, $text, $parameters = '', $cols = '50', $rows = '5', $reinsert_value = false) {
        //return tep_draw_textarea_field($name, '', $cols, $rows, $text, $parameters, $reinsert_value);
        return html::textarea_field($name, 'warp', $cols, $rows, $text, $parameters, $reinsert_value);
    }

    /**
     * 生成下拉选择框
     * @param string $name       下拉框名称
     * @param array  $values     下拉数据array(array('id'=>'ID','text'=>'名称')[,array('id'=>'ID','text'=>'名称')[,...]])
     * @param string $default    默认选中的那个ID值
     * @param string $parameters 其他下拉框的属性
     * @param bool   $required   是否必填项
     * @author lwkai 14-2-25
     * @return string
     */
    public static function inputSelect($name, array $values, $default = '', $parameters = '', $required = false) {
        return html::select_field($name, $values, $default, $parameters, $required);
    }

    /**
     * 生成可多选的下拉Select菜单
     * @param string     $name 下拉框名称
     * @param array      $values 下拉数据array(array('id'=>'ID','text'=>'名称')[,array('id'=>'ID','text'=>'名称')[,...]])
     * @param array      $default 默认选中的值（一维数组）
     * @param string     $parameters 其他下拉框的属性
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     * @date   2017-03-08
     */
    public static function inputSelectMultiple($name, array $values, array $default = array(), $parameters = ''){
        return html::select_field_multiple($name, $values, $default, $parameters);
    }
    /**
     * 生成复选框
     * @param string $name       复选框名称
     * @param string $value      复选框值
     * @param bool   $checked    是否已经选中状态
     * @param string $parameters 其他html属性
     * @return string
     * @author lwkai
     * @date   14-3-4
     */
    public static function inputCheckbox($name = '', $value = '', $checked = false, $parameters = '') {
        return html::input_checkbox_field($name, $value, $checked, $parameters);
    }

    /**
     * 把$_GET参数生成为隐藏域表单
     * @param array  $get     $_GET 对象
     * @param array  $remove  需要排除的参数名称数组
     * @param string $key_str 此参数，供递归用的。不需要传值
     * @return string
     * @author lwkai
     * @date   14-3-1
     */
    public static function getToHiddenInput(array $get, $remove = array(), $key_str = '') {
        $rtn = '';
        foreach ($get as $key => $value) {
            if (($key !== session_name()) && ($key !== 'error') && (!in_array($key, $remove))) {
                if (is_array($value)) {
                    if ($key_str == '') {
                        $rtn .= self::getToHiddenInput($value, array(), $key . '[');
                    } else {
                        $rtn .= self::getToHiddenInput($value, array(), $key_str . $key . '][');
                    }
                } else {
                    if ($key_str == '') {
                        $rtn .= self::inputHidden($key, Strings::SafeOut($value));
                    } else {
                        $rtn .= self::inputHidden($key_str . $key . ']', Strings::SafeOut($value));
                    }
                }
            }
        }
        return $rtn;
    }

    /**
     * 使用一维数组创建SELECT元素 格式为array('value'=>'name')
     * @param array      $info
     * @param string     $name     生成的下拉列表的名称
     * @param int|string $default  选中的值
     * @param string     $onchange 当改变的时候进行的动作
     * @param int|string $size     size的数量
     * @param string     $parameters
     * @return string
     */
    public static function drawSelect($info, $name, $default, $onchange = '', $size = '', $parameters = '') {
        $rtn  = array();
        $mark = false;
        foreach ($info as $key => $val) {
            if ((is_string($key) && is_null($key) && $mark == false))
                die('1');
            (!$key && $mark == false) ? $mark = true : '';
            (is_int($key) && $key <= 0 && $mark == false) ? $mark = true : '';

            $rtn[] = array('id' => $key, 'text' => $val);
        }
        if (!$mark && !$size)
            array_unshift($rtn, array('id' => 0, 'text' => '=ALL='));
        $size ? $size = 'size="' . $size . '"' : '';
        $onchange ? $onchange = 'onchange="' . $onchange . '" ' : '';
        return self::inputSelect($name, $rtn, $default, $onchange . ' ' . $size . ' ' . $parameters);
    }

    public static function  selectHabits($name, $input_option, $habits_option, $select_function) {
        if ($habits_option) {
            $habits_option = $habits_option[$name];
            foreach ($habits_option as $key => $v) {
                $info[$key] = $input_option[$key];
                unset($input_option[$key]);
            }
            $info += $input_option;
        } else {
            $info = $input_option;
        }

        return self::drawSelect($info, $name, key($info), $select_function, 1);
    }

    /**
     * 生成一个单行文件框
     * @param $name   名称
     * @param $params 其他属性
     * @return string
     * @author chankit 14-4-14
     */
    public static function file($name, $params = '') {
        //return tep_draw_input_field($name, '', $params, false, 'file', false);
        return html::input_field($name, '', $params, 'file');
    }

    /**
     * 非阻塞式访问某个页面。 应用场景：如访问一个smtp发邮件的服务页面，不用等待即可执行此后面的代码，大大节约程序时间！
     * @param       $url
     * @param array $post_data
     * @param array $cookie
     * @return bool
     * @author ZhouHaoHua <53027327@qq.com>
     */
    public static function triggerRequest($url, $post_data = array(), $cookie = array()){
        return \Z::Network()->triggerRequest($url, $post_data, $cookie );
    }
}